#pragma once

#include<memory>
#include<functional>
#include<sys/wait.h>
#include"socket.hpp"
#include"inetaddr.hpp"

using handle_t=std::function<void(SockPtr&,inetaddr&)>;
class tcpserver{
public:
    tcpserver(uint16_t port):_port(port),_isrunning(false)
    {
        _listen_sock_ptr=std::make_shared<TcpSocket>();
        _listen_sock_ptr->BulitTcpSocket(_port);        //创建，绑定，监听都会一起完成
    }

    void sethandle(handle_t handle){
        _server_handle=handle;
    }

    void loop(){
        _isrunning=true;

        while(_isrunning){
            inetaddr client;
            SockPtr sock_ptr=_listen_sock_ptr->accept(&client);
            
            pid_t id=fork();
            if(id==0){
                _listen_sock_ptr->closeSocket();
                if(fork()>0) exit(0);
                _server_handle(sock_ptr,client);
            }
            sock_ptr->closeSocket();
            ::waitpid(id,nullptr,0);

        }

        _isrunning=false;
    }

    ~tcpserver()
    {
        _listen_sock_ptr->closeSocket();                //关闭socket
    }
private:
    uint16_t _port;
    SockPtr _listen_sock_ptr;
    bool _isrunning;
    handle_t _server_handle;
};